import pandas as pd
import numpy as np
import umap
#import seaborn as sns
import plotly.express as px
#pip install pyarrow
#pip install seaborn
#pip install umap-learn
from sklearn.preprocessing import StandardScaler
#Train
data1 = pd.read_parquet('train_numerical_features.parquet')
data2 = pd.read_parquet('train_text_features.parquet')
data = data1.merge(data2, on = ['id', 'tagline', 'credits', 'title'])
data.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 9641 entries, 0 to 9640 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 9641 non-null int64 1 title 9641 non-null object 2 budget 9641 non-null float64 3 revenue 9641 non-null float64 4 runtime 9641 non-null float64 5 status 9641 non-null object 6 tagline 7603 non-null object 7 credits 9623 non-null object 8 poster_path 9641 non-null object 9 backdrop_path 9632 non-null object 10 recommendations 9639 non-null object 11 genres 9639 non-null object 12 original_language 9641 non-null object 13 overview 9628 non-null object 14 production_companies 9565 non-null object 15 release_date 9641 non-null object 16 keywords 9052 non-null object 17 vote_average 9641 non-null float64 dtypes: float64(4), int64(1), object(13) memory usage: 1.4+ MB
data.drop(['poster_path', 'backdrop_path', 'recommendations'], axis=1, inplace=True)
data = data[~ (
(data['revenue']==0) |
(data['release_date'].isna()) |
(data['runtime'].isna()) |
((data['status'] != 'Released'))
)]
data['release_date'] = pd.to_datetime(data['release_date'], format = '%Y-%m-%d')
data_cat = data.select_dtypes(include=[object])
data[data_cat.columns] = data_cat.fillna('')
data.loc[:, 'label'] = 'Very Positive'
data.loc[(data['vote_average'] <= 8) & (data['vote_average'] > 7), 'label'] = 'Positive'
data.loc[(data['vote_average'] <= 7) & (data['vote_average'] > 6), 'label'] = 'Mostly Positive'
data.loc[(data['vote_average'] <= 6) & (data['vote_average'] > 5), 'label'] = 'Mixed'
data.loc[(data['vote_average'] <= 5) , 'label'] = 'Negative'
data.drop(['vote_average', 'id', 'status'], axis=1, inplace=True)
data.rename(columns = {'revenue':'target'},
inplace=True)
data.head(3)
| title | budget | target | runtime | tagline | credits | genres | original_language | overview | production_companies | release_date | keywords | label | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Fantastic Beasts: The Secrets of Dumbledore | 200000000.0 | 400000000.0 | 142.0 | Return to the magic. | Jude Law-Eddie Redmayne-Mads Mikkelsen-Ezra Mi... | Fantasy-Adventure-Action | en | Professor Albus Dumbledore knows the powerful ... | Warner Bros. Pictures-Heyday Films | 2022-04-06 | magic-curse-fantasy world-wizard-magical creat... | Mostly Positive |
| 1 | Sonic the Hedgehog 2 | 110000000.0 | 393000000.0 | 122.0 | Welcome to the next level. | James Marsden-Ben Schwartz-Tika Sumpter-Natash... | Action-Adventure-Family-Comedy | en | After settling in Green Hills Sonic is eager t... | Original Film-Blur Studio-Marza Animation Plan... | 2022-03-30 | sequel-based on video game-hedgehog-live actio... | Positive |
| 2 | The Lost City | 74000000.0 | 164289828.0 | 112.0 | The adventure is real. The heroes are not. | Sandra Bullock-Channing Tatum-Daniel Radcliffe... | Action-Adventure-Comedy | en | A reclusive romance novelist was sure nothing ... | Paramount-Fortis Films-3dot Productions-Exhibi... | 2022-03-24 | duringcreditsstinger | Mostly Positive |
data.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 6451 entries, 0 to 9636 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 title 6451 non-null object 1 budget 6451 non-null float64 2 target 6451 non-null float64 3 runtime 6451 non-null float64 4 tagline 6451 non-null object 5 credits 6451 non-null object 6 genres 6451 non-null object 7 original_language 6451 non-null object 8 overview 6451 non-null object 9 production_companies 6451 non-null object 10 release_date 6451 non-null datetime64[ns] 11 keywords 6451 non-null object 12 label 6451 non-null object dtypes: datetime64[ns](1), float64(3), object(9) memory usage: 705.6+ KB
data.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 6451 entries, 0 to 9636 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 title 6451 non-null object 1 budget 6451 non-null float64 2 target 6451 non-null float64 3 runtime 6451 non-null float64 4 tagline 6451 non-null object 5 credits 6451 non-null object 6 genres 6451 non-null object 7 original_language 6451 non-null object 8 overview 6451 non-null object 9 production_companies 6451 non-null object 10 release_date 6451 non-null datetime64[ns] 11 keywords 6451 non-null object 12 label 6451 non-null object dtypes: datetime64[ns](1), float64(3), object(9) memory usage: 705.6+ KB
Tenemos 3 columnas numéricas, 1 de temporal y 9 que representan texto. Dado el preprocesamiento inicial, ya no hay datos faltantes.
data_num = data.select_dtypes(include=[np.number])
for col in data_num.columns:
fig = px.histogram(data, x=col,
title=f'Histograma de la variable "{col}"')
fig.show()
fig = px.imshow(data_num.corr(), text_auto=True)
fig.show()
La correlación de variables numéricas muestra que las películas con mayor presupuesto (budget) tienden a tener más ingresos. Esto puede deberse a que grandes cadenas destinen mucho dinero en hacer películas muy atractivas para la audiencia (por ej. Marvel). No hay una relación clara entre duración y variables monetarias.
reducer = umap.UMAP()
scaled_num_data = StandardScaler().fit_transform(data_num.values)
embedding = reducer.fit_transform(scaled_num_data)
#embedding = reducer.fit_transform(data_num.values)
fig = px.scatter(x= embedding[:, 0], y = embedding[:, 1], color = data['label'])
fig.show()
La reducción de dimensionalidad muestra una leve diferencia entre las reseñas muy positivas y las negativas, las cuales se encuentran en lados opuestos de la gráfica. Los otros tipos de calificaciones se encuentran entre ambos extremos y abarcan la region media.
fig = px.scatter(y = data_num['budget'], x = data_num['target'], color = data['label'])
fig.show()
Del gráfico anterior una pelicula con mayor presupuesto no garantiza una mayor ganancia, pero si hay una correlación positiva entre ambas. Además, la mayoría de las peliculas con poca recaudación son mal evaluadas; por el contrario, mientras mayor recaudación, mejor evaluadas son.
fig = px.scatter(y = data_num['runtime'], x = data_num['target'], color = data['label'])
fig.show()
Para la duración de la pelicula, no pareciera haber una correlación entre el tiempo, la clasificación y las ganancias obtenidas.
fig = px.scatter(x = data_num['runtime'], y = data_num['budget'], color = data['label'])
fig.show()
La gráfica anterior muestra que películas con menor duració usualmente tienen un menor presupuesto, pero que esta no es la regla dado que hay peliculas de alta duración y presupuesto bajo.
data_cat = data[['genres', 'production_companies', 'credits', 'keywords', 'original_language']]
for col in data_cat.columns:
if col != 'original_language':
values = [x.split(sep='-') for x in data_cat[col].unique()]
values = [i for x in values for i in x]
else:
values = data_cat[col]
val_unique, counts = np.unique(values, return_counts=True)
series_count = pd.Series(counts, index = val_unique).sort_values(ascending = False).head(30)
fig = px.bar(y = series_count.index, x = series_count.values)
fig.show()
El gráfico anterior muestra la frecuencia de cada género en la base de datos. Los valores Drama, Action, Comedy y Adventure son los 4 más frecuentes, pero no hay una predominancia clara.